<template>
  <div>
    <div class="configerDiv">
      <div style="margin-top: 10px">
        <span class="title" onselectstart="return false;">
          Edit Configuration
        </span>
      </div>
      <el-divider></el-divider>
      <el-form
        :model="editConfiguration"
        size="medium "
        style="width: 200px; margin-top: 10px; padding-left: 14px"
      >
        <el-form-item
          label="密度"
          prop="distance"
          :rules="[
            { required: false, message: '密度不能为空' },
            { type: 'number', message: '密度必须为数字值' },
          ]"
        >
          <el-input
            type="number"
            v-model.number="editConfiguration.distance"
            autocomplete="off"
            style="width: 160px"
          ></el-input>
        </el-form-item>

        <el-form-item label="算法">
          <el-select
            v-model="editConfiguration.value"
            style="width: 160px"
            @change="algoSelect"
          >
            <el-option
              v-for="item in editConfiguration.algo"
              :key="item.value"
              :label="item.name"
              :value="item.value"
              :disabled="item.disabled"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div style="margin-bottom: 10px">
        <el-button @click="dataVisualible" style="margin-right: 10px"
          >提交</el-button
        >
        <el-button @click="download" style="margin-left: 10px">下载</el-button>
      </div>
    </div>
    <div id="container"></div>
  </div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {
  CSS3DRenderer,
  CSS3DObject,
} from "three/examples/jsm/renderers/CSS3DRenderer.js";
import { IcosahedronGeometry } from "three";
export default {
  data() {
    return {
      editConfiguration: {
        distance: 4,
        algo: [
          { value: 0, name: "正四面体划分" },
          { value: 1, name: "正八面体划分" },
          { value: 2, name: "正十二面体划分" },
          { value: 3, name: "正二十面体划分" },
          { value: 4, name: "四面体划分del3d" },
          { value: 5, name: "四面体划分front3d" },
          { value: 6, name: "四面体划分mmg3d" },
          { value: 7, name: "四面体划分hxt" },
        ],
        value: 0,
      },
      camera: null,
      scene: null,
      renderer: null,
      mesh: null,
      controls: null,
      meshNodes: [],
      meshElements: [],

      /***UV */
      vertexBuffer: [],
      uvBuffer: [],
      vertices: [],
      faces: [],
      faceVertexUvs: [],
    };
  },
  methods: {
    algoSelect(value) {
      switch (value) {
        case 0:
          this.editConfiguration.distance = 4;
          break;
        case 1:
          this.editConfiguration.distance = 3;
          break;
        case 2:
          this.editConfiguration.distance = 2;
          break;
        case 3:
          this.editConfiguration.distance = 2;
          break;
        case 4:
          this.editConfiguration.distance = 20;
          break;
        case 5:
          this.editConfiguration.distance = 20;
          break;
        case 6:
          this.editConfiguration.distance = 20;
          break;
        case 7:
          this.editConfiguration.distance = 20;
          break;

        default:
          break;
      }
    },
    fake_click(obj) {
      var ev = document.createEvent("MouseEvents");
      ev.initMouseEvent(
        "click",
        true,
        false,
        window,
        0,
        0,
        0,
        0,
        0,
        false,
        false,
        false,
        false,
        0,
        null
      );
      obj.dispatchEvent(ev);
    },
    download() {
      var name = "test.txt";
      var data = "/******Mesh Node******/\n";
      for (let i = 0; i < this.meshNodes.length; i++) {
        const tempMeshNode = this.meshNodes[i];
        data += i + " ";
        for (let j = 0; j < tempMeshNode.length; j++) {
          const elementNode = tempMeshNode[j];
          data += elementNode + " ";
        }
        data += "\n";
      }
      data += "/******Mesh Element******/\n";
      for (let i = 0; i < this.meshElements.length; i++) {
        const tempMeshElement = this.meshElements[i];
        data += i + " ";
        for (let j = 0; j < tempMeshElement.length; j++) {
          const elementElement = tempMeshElement[j];
          data += elementElement + " ";
        }
        data += "\n";
      }
      var urlObject = window.URL || window.webkitURL || window;

      var downloadData = new Blob([data]);

      var save_link = document.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "a"
      );
      save_link.href = urlObject.createObjectURL(downloadData);
      save_link.download = name;
      this.fake_click(save_link);
    },
    async dataVisualible() {
      switch (this.editConfiguration.value) {
        case 0:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }

          this.createPolyhedralDivisionGeometry(
            0,
            this.editConfiguration.distance
          );
          break;
        case 1:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }

          this.createPolyhedralDivisionGeometry(
            1,
            this.editConfiguration.distance
          );

          break;
        case 2:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }

          this.createPolyhedralDivisionGeometry(
            2,
            this.editConfiguration.distance
          );
          break;
        case 3:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }

          this.createPolyhedralDivisionGeometry(
            3,
            this.editConfiguration.distance
          );
          break;
        case 4:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }
          await this.getData();
          this.createunstructTriangle();
          break;
        case 5:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }
          await this.getData();
          this.createunstructTriangle();
          break;
        case 6:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }
          await this.getData();
          this.createunstructTriangle();
          break;
        case 7:
          if (this.scene.children.length == 16) {
            this.scene.children.splice(this.scene.children.length - 2, 2);
          }
          await this.getData();
          this.createunstructTriangle();
          break;
        default:
          break;
      }
    },
    test() {
      var material = new THREE.MeshStandardMaterial({
        color: 0x00cc00,
        side: THREE.DoubleSide,
      });

      //创建仅有一个三角面片的几何体
      var geometry = new THREE.Geometry();
      geometry.vertices.push(new THREE.Vector3(0, 0, 10));
      geometry.vertices.push(new THREE.Vector3(10, 0, 0));
      geometry.vertices.push(new THREE.Vector3(0, 10, 0));
      geometry.vertices.push(new THREE.Vector3(10, 10, 10));

      //利用顶点 0, 1, 2 创建一个面
      var normal = new THREE.Vector3(0, 1, 0); //optional
      var color = new THREE.Color(0xffaa00); //optional
      var materialIndex = 0; //optional
      var face = new THREE.Face3(0, 1, 2);

      //将创建的面添加到几何体的面的队列
      geometry.faces.push(face);

      //如果没有特别指明，面和顶点的法向量可以通过如下代码自动计算
      geometry.computeFaceNormals();
      geometry.computeVertexNormals();

      this.scene.add(new THREE.Mesh(geometry, material));
    },
    async getData() {
      var _this = this;
      var postdata_temp;
      switch (this.editConfiguration.value) {
        case 4:
          postdata_temp = {
            algo: "del3d",
            distance: this.editConfiguration.distance,
          };
          break;
        case 5:
          postdata_temp = {
            algo: "front3d",
            distance: this.editConfiguration.distance,
          };
          break;
        case 6:
          postdata_temp = {
            algo: "mmg3d",
            distance: this.editConfiguration.distance,
          };
          break;
        case 7:
          postdata_temp = {
            algo: "hxt",
            distance: this.editConfiguration.distance,
          };
          break;

        default:
          break;
      }

      await axios
        .post("http://localhost:8181/getSurUstrTri", postdata_temp)
        .then(function (resp) {
          _this.meshNodes = resp.data.node;
          _this.meshElements = resp.data.element;
          console.log("meshData", resp);
        });
    },
    createFaceMesh() {
      // var material = new THREE.MeshNormalMaterial({
      //   color: 0xff0000,
      //   side: THREE.DoubleSide,
      // });
      var material1 = new THREE.MeshBasicMaterial({
        vertexColors: THREE.VertexColors,
        wireframe: false,
        side: THREE.DoubleSide,
      });

      //创建仅有一个三角面片的几何体
      var color1 = new THREE.Color(0xff0000);
      var color2 = new THREE.Color(0x0000ff);
      var color3 = new THREE.Color(0x00ff00);

      var geometry = new THREE.Geometry();
      // geometry.vertices.push(new THREE.Vector3(10, 0, 0));
      // geometry.vertices.push(new THREE.Vector3(0, 10, 0));
      // geometry.vertices.push(new THREE.Vector3(0, 0, 10));
      // var face1 = new THREE.Face3(0, 1, 2);
      // face1.vertexColors[0] = color1;
      // face1.vertexColors[1] = color2;
      // face1.vertexColors[2] = color3;
      // geometry.faces.push(face1);
      for (let i = 0; i < this.meshNodes.length; i++) {
        const trinode = this.meshNodes[i];
        geometry.vertices.push(
          new THREE.Vector3(trinode[0], trinode[1], trinode[2])
        );
      }

      for (let i = 0; i < this.meshElements.length; i++) {
        const triElement = this.meshElements[i];
        //利用顶点 创建一个面
        var face1 = new THREE.Face3(
          triElement[0],
          triElement[1],
          triElement[2]
        );
        face1.vertexColors[0] = color1;
        face1.vertexColors[1] = color2;
        face1.vertexColors[2] = color3;
        var face2 = new THREE.Face3(
          triElement[0],
          triElement[1],
          triElement[3]
        );
        face2.vertexColors[0] = color1;
        face2.vertexColors[1] = color2;
        face2.vertexColors[2] = color3;
        var face3 = new THREE.Face3(
          triElement[0],
          triElement[2],
          triElement[3]
        );
        face3.vertexColors[0] = color1;
        face3.vertexColors[1] = color2;
        face3.vertexColors[2] = color3;
        var face4 = new THREE.Face3(
          triElement[1],
          triElement[2],
          triElement[3]
        );
        face4.vertexColors[0] = color1;
        face4.vertexColors[1] = color2;
        face4.vertexColors[2] = color3;
        //将创建的面添加到几何体的面的队列
        geometry.faces.push(face1);
        geometry.faces.push(face2);
        geometry.faces.push(face3);
        geometry.faces.push(face4);
      }

      //如果没有特别指明，面和顶点的法向量可以通过如下代码自动计算
      // geometry.computeFaceNormals();
      // geometry.computeVertexNormals();
      var obj = new THREE.Mesh(geometry, material1);
      this.scene.add(obj);
      // this.createMesh();
    },
    createLineMesh() {
      // 四面体
      var gemetries = new THREE.Geometry();
      // 表面网格
      var gemetriesSurface = new THREE.Geometry();

      var materier = new THREE.LineBasicMaterial({
        color: 0xffffff,
        side: THREE.DoubleSide,
      });

      var materierSurface = new THREE.LineBasicMaterial({
        color: 0x00ff00,
        side: THREE.DoubleSide,
      });

      for (let i = 0; i < this.meshElements.length; i++) {
        const triElement = this.meshElements[i];
        //利用顶点 画线
        var points = new Array();
        var pointsSurface = new Array();

        for (let j = 0; j < triElement.length; j++) {
          let tempPoint = this.meshNodes[triElement[j]];

          points.push(
            new THREE.Vector3(tempPoint[0], tempPoint[1], tempPoint[2])
          );
          let radius = Math.sqrt(
            tempPoint[0] * tempPoint[0] +
              tempPoint[1] * tempPoint[1] +
              tempPoint[2] * tempPoint[2]
          );
          if (Math.abs(radius - 100) < 10) {
            pointsSurface.push(
              new THREE.Vector3(tempPoint[0], tempPoint[1], tempPoint[2])
            );
          }
        }
        if (pointsSurface.length != 3) {
          continue;
        }

        for (let k = 0; k < pointsSurface.length; k++) {
          for (let l = k + 1; l < pointsSurface.length; l++) {
            gemetriesSurface.vertices.push(pointsSurface[k]);
            gemetriesSurface.vertices.push(pointsSurface[l]);
          }
        }

        // for (let k = 0; k < points.length; k++) {
        //   for (let l = k + 1; l < points.length; l++) {
        //     gemetries.vertices.push(points[k]);
        //     gemetries.vertices.push(points[l]);
        //   }
        // }
      }

      var lineSurface = new THREE.LineSegments(
        gemetriesSurface,
        materierSurface
      ); // var line = new THREE.Line(gemetries, materier, THREE.LineSegments);
      // this.scene.add(line);
      this.scene.add(lineSurface);
    },
    createSurfaceMesh() {
      // var material1 = new THREE.MeshBasicMaterial({
      //   color: 0x00ff00,
      //   side: THREE.DoubleSide,
      // });

      var geometry = new THREE.Geometry();

      // }
      var planeCoor = new Array();
      for (let i = 0; i < this.meshElements.length; i++) {
        const triElement = this.meshElements[i];
        //利用顶点 画线

        var pointsSurface = new Array();

        for (let j = 0; j < triElement.length; j++) {
          let tempPoint = this.meshNodes[triElement[j]];

          let radius = Math.sqrt(
            tempPoint[0] * tempPoint[0] +
              tempPoint[1] * tempPoint[1] +
              tempPoint[2] * tempPoint[2]
          );
          if (Math.abs(radius - 100) < 10) {
            pointsSurface.push(
              new THREE.Vector3(tempPoint[0], tempPoint[1], tempPoint[2])
            );
          }
        }
        // 抽取表面的点

        if (pointsSurface.length != 3) {
          continue;
        } else {
          for (let j = 0; j < pointsSurface.length; j++) {
            geometry.vertices.push(pointsSurface[j]);
            planeCoor.push(
              this.xyztouv(
                pointsSurface[j].x,
                pointsSurface[j].y,
                pointsSurface[j].z
              )
            );
          }
        }
        let face = new THREE.Face3(
          geometry.vertices.length - 1,
          geometry.vertices.length - 2,
          geometry.vertices.length - 3
        );
        geometry.faces.push(face);
      }
      console.log("planeCoor", planeCoor);
      //如果没有特别指明，面和顶点的法向量可以通过如下代码自动计算
      geometry.computeFaceNormals();
      geometry.computeVertexNormals();
      var group = new THREE.Group();
      this.scene.add(group);

      var geometry1 = new THREE.PlaneGeometry(500, 300);

      var globeTextureLoader = new THREE.TextureLoader();
      globeTextureLoader.load("earthtex1.jpg", function (texture) {
        var globeMaterial = new THREE.MeshStandardMaterial({
          map: texture,
          wireframe: false,
          side: THREE.DoubleSide,
        });
        var globeMesh = new THREE.Mesh(geometry, globeMaterial);

        // group.add(geometry, line3);
        group.add(globeMesh);
      });
      var edges3 = new THREE.EdgesGeometry(geometry);
      var edgesMaterial = new THREE.LineBasicMaterial({
        color: 0xffffff,
      });
      var line3 = new THREE.LineSegments(edges3, edgesMaterial);
      // var obj = new THREE.Mesh(geometry, material1);
      this.scene.add(line3);
      console.log(geometry);

      // this.createMesh();
    },
    createPolyhedralDivisionGeometry(algovalue, defaultpar) {
      console.log("this.scene", this.scene);
      var Polyhedral;
      switch (algovalue) {
        case 0:
          Polyhedral = new THREE.TetrahedronGeometry(100, defaultpar);
          break;
        case 1:
          Polyhedral = new THREE.OctahedronGeometry(100, defaultpar);
          break;
        case 2:
          Polyhedral = new THREE.DodecahedronGeometry(100, defaultpar);
          break;
        case 3:
          Polyhedral = new THREE.IcosahedronGeometry(100, defaultpar);
          break;
        default:
          Polyhedral = new THREE.IcosahedronGeometry(100, defaultpar);
          break;
      }

      var faces = Polyhedral.faces;
      var vertices = Polyhedral.vertices;
      for (let i = 0; i < vertices.length; i++) {
        this.meshNodes.push([vertices[i].x, vertices[i].y, vertices[i].z]);
      }
      for (let i = 0; i < faces.length; i++) {
        this.meshElements.push([faces[i].a, faces[i].b, faces[i].c]);
      }

      // console.log(this.meshNodes);
      // console.log(this.meshElements);
      console.log(Polyhedral);
      var _this = this;
      // 图片加载器
      var ImageLoader = new THREE.ImageLoader();
      // load方法回调函数，按照路径加载图片，返回一个html的元素img对象
      ImageLoader.load("earthtex1.jpg", function (img) {
        // image对象作为参数，创建一个纹理对象Texture
        var texture = new THREE.Texture(img);
        // 下次使用纹理时触发更新
        texture.needsUpdate = true;
        var material = new THREE.MeshBasicMaterial({
          map: texture, //设置纹理贴图
        });
        var mesh = new THREE.Mesh(Polyhedral, material); //网格模型对象Mesh
        _this.scene.add(mesh); //网格模型添加到场景中

        //添加轮廓线
        var edges = new THREE.EdgesGeometry(Polyhedral);
        var edgesMaterial = new THREE.LineBasicMaterial({
          color: 0xffffff,
        });
        var line3 = new THREE.LineSegments(edges, edgesMaterial);
        _this.scene.add(line3);
      });
    },
    createIcosahedronGeometry() {
      // 正二十面体
      var IcosahedronGgeometry = new THREE.IcosahedronGeometry(100, 1);
      var faces = IcosahedronGgeometry.faces;
      var vertices = IcosahedronGgeometry.vertices;
      for (let i = 0; i < vertices.length; i++) {
        this.meshNodes.push([vertices[i].x, vertices[i].y, vertices[i].z]);
      }
      for (let i = 0; i < faces.length; i++) {
        this.meshElements.push([faces[i].a, faces[i].b, faces[i].c]);
      }

      // console.log(this.meshNodes);
      // console.log(this.meshElements);
      console.log(IcosahedronGgeometry);
      var _this = this;
      // 图片加载器
      var ImageLoader = new THREE.ImageLoader();
      // load方法回调函数，按照路径加载图片，返回一个html的元素img对象
      ImageLoader.load("earthtex1.jpg", function (img) {
        // image对象作为参数，创建一个纹理对象Texture
        var texture = new THREE.Texture(img);
        // 下次使用纹理时触发更新
        texture.needsUpdate = true;
        var material = new THREE.MeshStandardMaterial({
          map: texture, //设置纹理贴图
        });
        var mesh = new THREE.Mesh(IcosahedronGgeometry, material); //网格模型对象Mesh
        _this.scene.add(mesh); //网格模型添加到场景中

        //添加轮廓线
        var edges = new THREE.EdgesGeometry(IcosahedronGgeometry);
        var edgesMaterial = new THREE.LineBasicMaterial({
          color: 0xffffff,
        });
        var line3 = new THREE.LineSegments(edges, edgesMaterial);
        _this.scene.add(line3);
      });
    },
    createIcosahedronGeometryTest() {
      var IcosahedronGgeometry = new THREE.IcosahedronGeometry(100, 2);
      var faces = IcosahedronGgeometry.faces;
      var vertices = IcosahedronGgeometry.vertices;
      var uvIcosahedron = IcosahedronGgeometry.faceVertexUvs[0];
      this.vertexBuffer = [];
      this.uvBuffer = [];
      for (let i = 0; i < vertices.length; i++) {
        this.vertexBuffer.push(vertices[i].x);
        this.vertexBuffer.push(vertices[i].y);
        this.vertexBuffer.push(vertices[i].z);
        this.meshNodes.push([vertices[i].x, vertices[i].y, vertices[i].z]);
      }

      for (let i = 0; i < faces.length; i++) {
        this.meshElements.push([faces[i].a, faces[i].b, faces[i].c]);
      }

      this.generateUVs();

      var geometry = new THREE.Geometry();
      geometry.faces = IcosahedronGgeometry.faces;
      geometry.vertices = IcosahedronGgeometry.vertices;
      for (let i = 0; i < this.meshElements.length; i++) {
        const triElement = this.meshElements[i];
        //利用顶点画线

        var pointsSurface = new Array();
        var faceuv = new Array();
        var facevertices = new Array();
        for (let j = 0; j < triElement.length; j++) {
          let tempPoint = this.meshNodes[triElement[j]];
          facevertices.push(tempPoint);
          faceuv.push(
            new THREE.Vector2(
              this.uvBuffer[triElement[j] * 2],
              this.uvBuffer[triElement[j] * 2 + 1]
            )
          );

          // let radius = Math.sqrt(
          //   tempPoint[0] * tempPoint[0] +
          //     tempPoint[1] * tempPoint[1] +
          //     tempPoint[2] * tempPoint[2]
          // );
          // if (Math.abs(radius - 100) < 10) {
          //   pointsSurface.push(
          //     new THREE.Vector3(tempPoint[0], tempPoint[1], tempPoint[2])
          //   );
          // }
        }
        // 抽取表面的点

        // if (pointsSurface.length != 3) {
        //   continue;
        // } else {
        //   for (let j = 0; j < pointsSurface.length; j++) {
        //     geometry.vertices.push(pointsSurface[j]);
        //   }
        // }
        // let face = new THREE.Face3(
        //   geometry.vertices.length - 3,
        //   geometry.vertices.length - 2,
        //   geometry.vertices.length - 1
        // );
        // geometry.faces.push(face);
        if (i == 36) {
          console.log("facevertices", facevertices, "faceuv", [
            [faceuv[0].x, faceuv[0].y],
            [faceuv[1].x, faceuv[1].y],
            [faceuv[2].x, faceuv[2].y],
          ]);
        }
        this.correctUVs(facevertices, faceuv);
        this.correctSeam(faceuv);
        geometry.faceVertexUvs[0].push(faceuv);
        // geometry.faceVertexUvs[0].push(uvIcosahedron[i]);
      }

      // this.mergeVertices(geometry);
      geometry.computeFaceNormals();

      var tempfaceUvs1 = geometry.faceVertexUvs[0];
      var tempfaceUvs2 = IcosahedronGgeometry.faceVertexUvs[0];
      for (let index = 0; index < tempfaceUvs1.length; index++) {
        const element1 = tempfaceUvs1[index];
        const element2 = tempfaceUvs2[index];
        for (let index2 = 0; index2 < element1.length; index2++) {
          if (
            Math.abs(element1[index2].x - element2[index2].x) > 0.05 ||
            Math.abs(element1[index2].y - element2[index2].y) > 0.05
          ) {
            console.log(
              index,
              index2,
              "geometry",
              element1[index2],
              "IcosahedronGgeometrys",
              element2[index2],
              this.meshNodes[this.meshElements[index][index2]][0],
              this.meshNodes[this.meshElements[index][index2]][1],
              this.meshNodes[this.meshElements[index][index2]][2]
            );
            this.creatTextPosition(
              index + "",
              this.meshNodes[this.meshElements[index][index2]][0],
              this.meshNodes[this.meshElements[index][index2]][1],
              this.meshNodes[this.meshElements[index][index2]][2]
            );
          }
        }
      }

      var group = new THREE.Group();
      this.scene.add(group);

      var globeTextureLoader = new THREE.TextureLoader();
      globeTextureLoader.load("earthtex1.jpg", function (texture) {
        var globeMaterial = new THREE.MeshStandardMaterial({
          map: texture,
          wireframe: false,
          side: THREE.DoubleSide,
        });
        var globeMesh = new THREE.Mesh(geometry, globeMaterial);

        // group.add(geometry, line3);
        group.add(globeMesh);
      });
      var edges3 = new THREE.EdgesGeometry(geometry);
      var edgesMaterial = new THREE.LineBasicMaterial({
        color: 0xffffff,
      });
      var line3 = new THREE.LineSegments(edges3, edgesMaterial);
      // var obj = new THREE.Mesh(geometry, material1);
      this.scene.add(line3);

      // console.log("uvnew", uvnew);
      console.log(IcosahedronGgeometry);
      console.log(geometry);
      // this.createMesh();
    },
    createunstructTriangle() {
      this.vertexBuffer = [];
      this.uvBuffer = [];

      var geometry = new THREE.Geometry();
      // 提取表面点坐标
      for (let i = 0; i < this.meshElements.length; i++) {
        const tempTrianglet = this.meshElements[i];
        let tempCurrentPoint = [];
        for (let j = 0; j < tempTrianglet.length; j++) {
          const tempPoint = this.meshNodes[tempTrianglet[j]];
          let radius = Math.sqrt(
            tempPoint[0] * tempPoint[0] +
              tempPoint[1] * tempPoint[1] +
              tempPoint[2] * tempPoint[2]
          );
          if (Math.abs(radius - 100) < 5) {
            tempCurrentPoint.push([tempPoint[0], tempPoint[1], tempPoint[2]]);
          }
        }

        if (tempCurrentPoint.length == 3) {
          for (let tci = 0; tci < tempCurrentPoint.length; tci++) {
            this.vertexBuffer.push(tempCurrentPoint[tci][0]);
            this.vertexBuffer.push(tempCurrentPoint[tci][1]);
            this.vertexBuffer.push(tempCurrentPoint[tci][2]);
            geometry.vertices.push(
              new THREE.Vector3(
                tempCurrentPoint[tci][0],
                tempCurrentPoint[tci][1],
                tempCurrentPoint[tci][2]
              )
            );
          }
          let tempTriFace = new THREE.Face3(
            geometry.vertices.length - 3,
            geometry.vertices.length - 2,
            geometry.vertices.length - 1
          );
          geometry.faces.push(tempTriFace);
        } else {
          continue;
        }
      }

      console.log("this.vertexBuffer", this.vertexBuffer);

      this.generateUVs();
      var faces = geometry.faces;
      var vertices = geometry.vertices;
      this.meshNodes = [];
      this.meshElements = [];
      for (let i = 0; i < vertices.length; i++) {
        this.meshNodes.push([vertices[i].x, vertices[i].y, vertices[i].z]);
      }

      for (let i = 0; i < faces.length; i++) {
        this.meshElements.push([faces[i].a, faces[i].b, faces[i].c]);
      }
      for (let i = 0; i < this.meshElements.length; i++) {
        const triElement = this.meshElements[i];
        //利用顶点画线

        var pointsSurface = new Array();
        var faceuv = new Array();
        var facevertices = new Array();
        for (let j = 0; j < triElement.length; j++) {
          let tempPoint = this.meshNodes[triElement[j]];
          facevertices.push(tempPoint);
          faceuv.push(
            new THREE.Vector2(
              this.uvBuffer[triElement[j] * 2],
              this.uvBuffer[triElement[j] * 2 + 1]
            )
          );
        }
        this.correctUVs(facevertices, faceuv);
        this.correctSeam(faceuv);
        geometry.faceVertexUvs[0].push(faceuv);
      }
      geometry.computeFaceNormals();

      var group = new THREE.Group();
      this.scene.add(group);

      var globeTextureLoader = new THREE.TextureLoader();
      globeTextureLoader.load("earthtex1.jpg", function (texture) {
        var globeMaterial = new THREE.MeshBasicMaterial({
          map: texture,
          wireframe: false,
          side: THREE.DoubleSide,
        });
        var globeMesh = new THREE.Mesh(geometry, globeMaterial);

        // group.add(geometry, line3);
        group.add(globeMesh);
      });
      var edges3 = new THREE.EdgesGeometry(geometry);
      var edgesMaterial = new THREE.LineBasicMaterial({
        color: 0xffffff,
      });
      var line3 = new THREE.LineSegments(edges3, edgesMaterial);
      this.scene.add(line3);
      console.log("this.uvBuffer", this.uvBuffer);
      console.log(geometry);
    },
    createMesh() {
      var lineMaterial = new THREE.LineBasicMaterial({
        color: "#ffffff",
      });

      var trianglesGroup = new THREE.Group();

      for (let i = 0; i < this.meshElements.length; i++) {
        let geometry = new THREE.Geometry();

        const element = this.meshElements[i];
        element.forEach((cellIndex) => {
          geometry.vertices.push(
            new THREE.Vector3(
              this.meshNodes[cellIndex - 1][0],
              this.meshNodes[cellIndex - 1][1],
              this.meshNodes[cellIndex - 1][2]
            )
          );
        });
        let triangle = new THREE.LineLoop(geometry, lineMaterial);
        trianglesGroup.add(triangle);
      }

      this.scene.add(trianglesGroup);
    },
    createPoints() {
      var geometry = new THREE.SphereGeometry(1, 36, 36);
      // var material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
      // 点渲染模式
      var material = new THREE.PointsMaterial({
        color: 0xff0000,
        size: 0.1, //点对象像素尺寸
      }); //材质对象

      var pointsGroup = new THREE.Group();
      for (let i = 0; i < this.meshNodes.length; i++) {
        let point = new THREE.Points(geometry, material);
        point.position.set(
          this.meshNodes[i][0],
          this.meshNodes[i][1],
          this.meshNodes[i][2]
        );
        pointsGroup.add(point);
      }

      //点模型对象
      // var sphere = new THREE.Mesh(geometry, material);

      console.log("pointsGroupLength", pointsGroup.children);

      this.scene.add(pointsGroup);
    },
    creatTextPosition(text, x, y, z) {
      var fontName = "gentilis"; // helvetiker, optimer, gentilis, droid sans, droid serif
      var fontWeight = "bold"; // normal bold

      const loader = new THREE.FontLoader();
      var _this = this;
      loader.load(
        "fonts/" + fontName + "_" + fontWeight + ".typeface.json",
        function (font) {
          var textGeometry = new THREE.TextGeometry(text, {
            font: font,
            size: 4,
            height: 0,
            // curveSegments: 12,
            // bevelEnabled: true,
            // bevelThickness: 10,
            // bevelSize: 8,
            // bevelSegments: 5,
          });

          textGeometry.computeBoundingBox();

          const textMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });

          const meshtext = new THREE.Mesh(textGeometry, textMaterial);
          var centerOffset =
            -0.5 *
            (textGeometry.boundingBox.max.x - textGeometry.boundingBox.min.x);

          meshtext.position.set(x, y, z);

          _this.scene.add(meshtext);
        }
      );
    },
    createCoordinateAxis() {
      /**
       * 绘制坐标系
       */

      var originPositionX = 0;
      var originPositionY = 0;
      var originPositionZ = 0;
      var AxisLength = 50;
      var geometryX = new THREE.Geometry(); //声明一个几何体对象Geometry

      //顶点坐标添加到geometry对象
      geometryX.vertices.push(
        new THREE.Vector3(originPositionX, originPositionY, originPositionZ),
        new THREE.Vector3(
          originPositionX + AxisLength,
          originPositionY,
          originPositionZ
        )
      );

      var geometryY = new THREE.Geometry();
      geometryY.vertices.push(
        new THREE.Vector3(originPositionX, originPositionY, originPositionZ),
        new THREE.Vector3(
          originPositionX,
          originPositionY + AxisLength,
          originPositionZ
        )
      );

      var geometryZ = new THREE.Geometry();
      geometryZ.vertices.push(
        new THREE.Vector3(originPositionX, originPositionY, originPositionZ),
        new THREE.Vector3(
          originPositionX,
          originPositionY,
          originPositionZ + AxisLength
        )
      );

      //材质对象
      var materialX = new THREE.LineBasicMaterial({
        color: 0xff0000,
      });
      var materialY = new THREE.LineBasicMaterial({
        color: 0x008000,
      });
      var materialZ = new THREE.LineBasicMaterial({
        color: 0x0000ff,
      });

      //线条模型对象
      var axisX = new THREE.Line(geometryX, materialX);
      var axisY = new THREE.Line(geometryY, materialY);
      var axisZ = new THREE.Line(geometryZ, materialZ);

      // 添加标签
      var fontName = "gentilis"; // helvetiker, optimer, gentilis, droid sans, droid serif
      var fontWeight = "bold"; // normal bold

      const loader = new THREE.FontLoader();
      var _this = this;
      loader.load(
        "fonts/" + fontName + "_" + fontWeight + ".typeface.json",
        function (font) {
          var textGeometry = new THREE.TextGeometry("X", {
            font: font,
            size: 4,
            height: 0,
            // curveSegments: 12,
            // bevelEnabled: true,
            // bevelThickness: 10,
            // bevelSize: 8,
            // bevelSegments: 5,
          });
          var textGeometryY = new THREE.TextGeometry("Y", {
            font: font,
            size: 4,
            height: 0,
          });
          var textGeometryZ = new THREE.TextGeometry("Z", {
            font: font,
            size: 4,
            height: 0,
          });

          textGeometry.computeBoundingBox();
          textGeometryY.computeBoundingBox();
          textGeometryZ.computeBoundingBox();
          const textMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });

          const meshtext = new THREE.Mesh(textGeometry, textMaterial);
          var centerOffset_X =
            -0.5 *
            (textGeometry.boundingBox.max.x - textGeometry.boundingBox.min.x);
          var centerOffset_Y =
            -0.5 *
            (textGeometry.boundingBox.max.y - textGeometry.boundingBox.min.y);
          var centerOffset_Z =
            -0.5 *
            (textGeometry.boundingBox.max.z - textGeometry.boundingBox.min.z);

          meshtext.position.set(
            originPositionX + AxisLength,
            originPositionY + centerOffset_Y,
            originPositionZ
          );

          const meshY = new THREE.Mesh(textGeometryY, textMaterial);
          meshY.position.set(
            originPositionX + centerOffset_X,
            originPositionY + AxisLength - centerOffset_Y,
            originPositionZ
          );

          const meshZ = new THREE.Mesh(textGeometryZ, textMaterial);
          meshZ.position.set(
            originPositionX + centerOffset_X,
            originPositionY + centerOffset_Y,
            originPositionZ + AxisLength
          );

          _this.scene.add(meshtext);
          _this.scene.add(meshY);
          _this.scene.add(meshZ);
        }
      );

      /**
       * 添加坐标系
       */
      this.scene.add(axisX); //线条对象添加到场景中
      this.scene.add(axisY);
      this.scene.add(axisZ);
    },

    renderLine() {
      var _this = this;
      var loader = new THREE.FontLoader(); //新建字体对象
      //加载相应的字体，下面字体名和样式组成gentilis_bold.typeface.json 完整文件名
      var fontName = "gentilis"; //字体名
      var fontWeight = "bold"; //加粗字体"/src/assets/font/gentilis_bold.typeface.json"

      loader.load("gentilis_bold.typeface.json", function (response) {
        //注意response 这内容比较关键，是否能加载中文就看这个变量了，这个变量里面的glyphs，默认的几种只有英文
        var options = {
          size: 30, //字号大小，一般为大写字母的高度
          height: 10, //文字的厚度
          weight: "normal", //值为'normal'或'bold'，表示是否加粗
          font: response, //字体，默认是'helvetiker'，需对应引用的字体文件
          style: "normal", //值为'normal'或'italics'，表示是否斜体
          bevelThickness: 1, //倒角厚度
          bevelSize: 1, //倒角宽度
          curveSegments: 30, //弧线分段数，使得文字的曲线更加光滑
          bevelEnabled: true, //布尔值，是否使用倒角，意为在边缘处斜切
        };
        ////创建一个三维对象的文本作为一个单一的对象 text输入的文字 options 文字设置
        var textGeo = new THREE.TextGeometry("hello word", options);
        textGeo.computeBoundingBox();
        textGeo.computeVertexNormals();

        var centerOffset =
          -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x);

        var material = new THREE.MultiMaterial([
          new THREE.MeshPhongMaterial({
            color: 0xffffff,
            shading: THREE.FlatShading,
          }), // front
          new THREE.MeshPhongMaterial({
            color: 0xffffff,
            shading: THREE.SmoothShading,
          }), // side
        ]);
        //新建mesh,加入
        var mesh = new THREE.Mesh(textGeo, material);
        mesh.position.x = 0;
        mesh.position.y = 0;
        mesh.position.z = 0;

        // mesh.rotation.x = 0;
        // mesh.rotation.y = Math.PI * 2;

        //scene是实例化的场景，在场景中加入mesh
        _this.scene.add(mesh);
      });
    },
    // 初始化
    init() {
      let container = document.getElementById("container");

      /**
       * 相机设置
       */
      var mycamera = new THREE.PerspectiveCamera(
        50,
        container.clientWidth / container.clientHeight,
        1,
        1000
      );
      // mycamera.position.set(0, 150, 500);
      mycamera.position.x = 200;
      mycamera.position.y = 200;
      mycamera.position.z = 200;
      mycamera.lookAt(0, 0, 0);

      this.camera = mycamera;

      /**
       * 场景
       */
      this.scene = new THREE.Scene();

      this.scene.add(this.camera);
      // const light = new THREE.PointLight(0xffffff, 0.8);
      // this.camera.add(light);
      // this.scene.background = new THREE.Color(0xf0f0f0);

      /**
       * 渲染
       */
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      // this.renderer.setClearColor("rgb(255,255,255)", 1.0);
      container.appendChild(this.renderer.domElement);
      //创建控件对象
      this.createCoordinateAxis();

      this.initControls();
      // var group = new THREE.Group();
      // this.scene.add(group);
      // this.addEarth(group);

      // this.addStarts(group);
      // this.addLights(group);
      // this.controls = new OrbitControls(this.camera, this.labelRenderer.domElement);
    },
    initControls() {
      //controls = new THREE.OrbitControls( camera, renderer.domElement );
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);

      // 如果使用animate方法时，将此函数删除

      //controls.addEventListener( 'change', render );

      // 使动画循环使用时阻尼或自转 意思是否有惯性

      this.controls.enableDamping = false;

      //动态阻尼系数 就是鼠标拖拽旋转灵敏度

      //controls.dampingFactor = 0.25;

      //是否可以缩放

      this.controls.enableZoom = true;

      //是否自动旋转

      this.controls.autoRotate = false;

      //设置相机距离原点的最远距离

      this.controls.minDistance = 1;

      //设置相机距离原点的最远距离

      this.controls.maxDistance = 10000;

      //是否开启右键拖拽

      this.controls.enablePan = false;
    },
    // 动画控制
    animate() {
      requestAnimationFrame(this.animate);
      // this.mesh.rotation.x += 0.01;
      // this.mesh.rotation.y += 0.02;
      this.renderer.render(this.scene, this.camera);
      this.controls.update();
    },
    starForge() {
      /* 	Yep, it's a Star Wars: Knights of the Old Republic reference,
		are you really surprised at this point? 
												*/
      var starQty = 10000;
      var geometry = new THREE.Geometry();

      var materialOptions = {
        size: 1.0,
        // transparency: true,
        opacity: 0.7,
      };

      var starStuff = new THREE.PointsMaterial(materialOptions);

      // The wizard gaze became stern, his jaw set, he creates the cosmos with a wave of his arms

      for (var i = 0; i < starQty; i++) {
        var starVertex = new THREE.Vector3();
        var x, y, z;

        x = Math.random() * 2000 - 1000;
        y = Math.random() * 2000 - 1000;
        z = Math.random() * 2000 - 1000;

        if (x * x + y * y + z * z < 350 * 350) continue;

        starVertex.x = x;
        starVertex.y = y;
        starVertex.z = z;
        geometry.vertices.push(starVertex);
      }

      var stars = new THREE.Points(geometry, starStuff);
      this.scene.add(stars);
    },
    initBacground() {
      var colors = ["#FFFFFF"];
      var spheres = [];
      var materialOptions = {
        size: 1.0,

        opacity: 0.7,
      };
      var starStuff = new THREE.PointsMaterial(materialOptions);

      for (var i = 0; i < 100; i++) {
        var color = colors[Math.floor(Math.random() * 5)];
        var radius = Math.random() * 12;
        var geometry = new THREE.IcosahedronGeometry(radius, 0);
        // var material = new THREE.MeshPhongMaterial({
        //   color: color,
        //   shading: THREE.FlatShading,
        //   vertexColors: THREE.VertexColors,
        //   shininess: 0,
        //   side: THREE.DoubleSide,
        // });
        var sphere = new THREE.Mesh(geometry, starStuff);
        var x = (Math.random() - 0.5) * 200;
        var y = (Math.random() - 0.5) * 200;
        var z = (Math.random() - 0.5) * 200;
        if (x > 0) x + 600;
        if (x < 0) x - 600;
        if (y > 0) y + 600;
        if (y < 0) y - 600;
        if (z > 0) z + 600;
        if (z < 0) z - 600;

        sphere.position.x = x;
        sphere.position.y = y;
        sphere.position.z = z;

        sphere.velocity = {
          x: 0.01,
          y: 0.01,
          z: 0.01,
        };
        sphere.radius = radius;
        spheres.push(sphere);
        this.scene.add(sphere);
      }
    },
    addLights() {
      var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
      directionalLight.position.set(0, 1, 0);
      this.scene.add(directionalLight);

      var leftLight = new THREE.DirectionalLight(0xffffff, 0.5);
      leftLight.position.set(1, 0, 0);
      this.scene.add(leftLight);

      var rightLight = new THREE.DirectionalLight(0xffffff, 0.5);
      rightLight.position.set(1, 0, 0);
      this.scene.add(rightLight);

      var frontLight = new THREE.DirectionalLight(0xffffff, 0.5);
      frontLight.position.set(0, 0, 1);
      this.scene.add(frontLight);

      var backLight = new THREE.DirectionalLight(0xffffff, 0.5);
      backLight.position.set(0, 0, -1);
      this.scene.add(backLight);

      var bottomLight = new THREE.DirectionalLight(0xffffff, 0.5);
      bottomLight.position.set(0, -1, 0);
      this.scene.add(bottomLight);
    },
    addEarth(group) {
      var globeTextureLoader = new THREE.TextureLoader();
      globeTextureLoader.load("earthtex1.jpg", function (texture) {
        var globeGgeometry = new THREE.IcosahedronGeometry(100, 2);
        var globeMaterial = new THREE.MeshStandardMaterial({
          map: texture,
          wireframe: false,
        });
        var globeMesh = new THREE.Mesh(globeGgeometry, globeMaterial);

        var edges3 = new THREE.EdgesGeometry(globeGgeometry);
        var edgesMaterial = new THREE.LineBasicMaterial({
          color: 0xffffff,
        });
        var line3 = new THREE.LineSegments(edges3, edgesMaterial);
        group.add(globeGgeometry, line3);

        group.add(globeMesh);
        group.rotation.x = THREE.Math.degToRad(35);
        group.rotation.y = THREE.Math.degToRad(170);
        console.log("globeGgeometry", globeGgeometry);
      });
    },
    addLigth(group) {
      //光
      var hemisphereLight = new THREE.HemisphereLight(fxfffff, 0x333333, 2);
      hemisphereLight.position.x = 0;
      hemisphereLight.position.y = 0;
      hemisphereLight.position.z = -200;
      group.add(hemisphereLight);
    },
    addStarts(group) {
      var starsGeometry = new THREE.Geometry();
      for (var i = 0; i < 2000; i++) {
        var starVector = new THREE.Vector3(
          THREE.Math.randFloatSpread(2000),
          THREE.Math.randFloatSpread(2000),
          THREE.Math.randFloatSpread(2000)
        );
        starsGeometry.vertices.push(starVector);
        var starsMaterial = new THREE.PointsMaterial({ color: 0x888888 });
        var starsPoint = new THREE.Points(starsGeometry, starsMaterial);
        group.add(starsPoint);
      }
    },
    xyztouv(x, y, z) {
      var lon = 0;
      if (x > 0 && y > 0) {
        // 第一象限
        lon = Math.asin(y / Math.sqrt(x * x + y * y));
      } else if (x < 0 && y > 0) {
        // 第二象限
        lon = Math.PI / 2 + Math.asin(y / Math.sqrt(x * x + y * y));
      } else if (x < 0 && y < 0) {
        // 第三象限
        lon = -Math.PI / 2 + Math.asin(y / Math.sqrt(x * x + y * y));
      } else {
        // 第四象限
        lon = Math.asin(y / Math.sqrt(x * x + y * y));
      }

      var lat = Math.atan(z / Math.sqrt(x * x + y * y));
      if (x == 0 && y == 0) {
        if (z > 0) {
          lon = 0;
          lat = Math.PI / 2;
        } else {
          lon = 0;
          lat = -Math.PI / 2;
        }
      }

      // var xy = this.lonlattoxy(lon, lat);
      // if (xy[0] < this.xMin) this.xMin = xy[0];
      // if (xy[0] > this.xMax) this.xMax = xy[0];

      // if (xy[1] < this.yMin) this.yMin = xy[1];
      // if (xy[1] > this.yMax) this.yMax = xy[1];

      // var u = (xy[0] + 157.07963267948966) / (2 * 157.07963267948966);
      // var v = (xy[1] + 5.2383818553693535) / (2 * 5.2383818553693535);
      var u = (lon + Math.PI) / (2 * Math.PI);
      var v = (lat + Math.PI / 2) / Math.PI;

      return [u, v];
    },

    lonlattoxy(longitude, latitude) {
      var p0 = 180 / Math.PI;
      var p1 = (60 * 180) / Math.PI;
      var p2 = (60 * 60 * 180) / Math.PI;
      var zonWidth = 6; // 带宽

      if (longitude < 0) {
        longitude = longitude + 2 * Math.PI;
      }

      /**第一步 根据经纬度计算中央子午线精度差 */
      var l0 = (Math.floor((longitude * p0) / zonWidth) + 1) * zonWidth - 3; // 6°带中央子午线
      var l = (longitude * p0 - l0) / p0; //精度差

      var a = 100; //椭圆长半轴
      var b = 100; //椭圆短半轴
      var e1 = Math.sqrt(a * a - b * b) / a; //椭圆第一偏心率
      var e2 = Math.sqrt(a * a - b * b) / b; //椭圆第二偏心率

      /**第二步 根据椭球选择计算子午弧长公式 */
      // 子午圈曲率半径展开系数
      var m0 = a * (1 - e1 * e1);
      var m2 = (3 * e1 * e1 * m0) / 2;
      var m4 = (5 * e1 * e1 * m2) / 4;
      var m6 = (7 * e1 * e1 * m4) / 6;
      var m8 = (9 * e1 * e1 * m6) / 8;

      var a0 = m0 + m2 / 2 + (3 * m4) / 8 + (5 * m6) / 16 + (35 * m8) / 128;
      var a2 = m2 / 2 + m4 / 2 + (15 * m6) / 32 + (7 * m8) / 16;
      var a4 = m4 / 8 + (3 * m6) / 16 + (7 * m8) / 32;
      var a6 = m6 / 32 + m8 / 16;
      var a8 = m8 / 128;

      var X =
        a0 * latitude -
        (a2 * Math.sin(2 * latitude)) / 2 +
        (a4 * Math.sin(4 * latitude)) / 4 -
        (a6 * Math.sin(6 * latitude)) / 6 +
        (a8 * Math.sin(8 * latitude)) / 8;
      //        double X = 111133.861 * latitude - 16038.480 * Math.sin(2 * latitude) + 16.828 * Math.sin(4 * latitude) - 0.022 * Math.sin(6 * latitude);
      /** 第三步 计算正算公式中的各符号值*/
      var t = Math.tan(latitude);
      var fi = e2 * Math.cos(latitude);
      var N =
        a / Math.sqrt(1 - e1 * e1 * Math.sin(latitude) * Math.sin(latitude));

      /** 第四步 带入公式求高斯平面坐标*/
      var x =
        X +
        (N * Math.sin(latitude) * Math.cos(latitude) * l * l) / 2 +
        (N *
          Math.sin(latitude) *
          Math.pow(Math.cos(latitude), 3) *
          (5 - t * t - 9 * fi * fi) *
          Math.pow(l, 4)) /
          24;
      var y =
        N * Math.cos(latitude) * l +
        (N *
          Math.pow(Math.cos(latitude), 3) *
          (1 - t * t + fi * fi) *
          Math.pow(l, 3)) /
          6 +
        (N *
          Math.pow(Math.cos(latitude), 5) *
          (5 - 18 * t * t + Math.pow(t, 4)) *
          Math.pow(l, 5)) /
          120;

      return [x, y];
    },
    /***creat uv */

    generateUVs() {
      const vertex = new THREE.Vector3();

      for (let i = 0; i < this.vertexBuffer.length; i += 3) {
        vertex.x = this.vertexBuffer[i + 0];
        vertex.y = this.vertexBuffer[i + 1];
        vertex.z = this.vertexBuffer[i + 2];

        let u = this.azimuth(vertex) / 2 / Math.PI + 0.5;
        let v = this.inclination(vertex) / Math.PI + 0.5;

        this.uvBuffer.push(u, 1 - v);
      }

      // this.correctUVs();

      // this.correctSeam();
    },
    correctSeam(faceuv) {
      // handle case when face straddles the seam, see #3269

      // uv data of a single face
      const x0 = faceuv[0].x;
      const x1 = faceuv[1].x;
      const x2 = faceuv[2].x;

      const max = Math.max(x0, x1, x2);
      const min = Math.min(x0, x1, x2);
      // if (min == 0.20396624727924206) {
      //   console.log("stop");
      // }
      if (max > 0.7 && min < 0.3) {
        // console.log("here");
        if (x0 < 0.3) faceuv[0].x += 1;
        if (x1 < 0.3) faceuv[1].x += 1;
        if (x2 < 0.3) faceuv[2].x += 1;
      }
    },

    // Angle around the Y axis, counter-clockwise when looking from above.
    azimuth(vector) {
      return Math.atan2(vector.z, -vector.x);
    },
    // Angle above the XZ plane.
    inclination(vector) {
      return Math.atan2(
        -vector.y,
        Math.sqrt(vector.x * vector.x + vector.z * vector.z)
      );
    },
    correctUVs(facevertices, faceuv) {
      const a = new THREE.Vector3();
      const b = new THREE.Vector3();
      const c = new THREE.Vector3();

      a.set(facevertices[0][0], facevertices[0][1], facevertices[0][2]);
      b.set(facevertices[1][0], facevertices[1][1], facevertices[1][2]);
      c.set(facevertices[2][0], facevertices[2][1], facevertices[2][2]);

      // const zmin = Math.min(a.z, b.z, c.z);
      // const zmax = Math.max(a.z, b.z, c.z);
      // if (zmin * zmax < 0) {
      //   console.log(
      //     "old",
      //     [
      //       [faceuv[0].x, faceuv[0].y],
      //       [faceuv[1].x, faceuv[1].y],
      //       [faceuv[2].x, faceuv[2].y],
      //     ],
      //     "new",
      //     faceuv
      //   );
      // }
      const uvA = faceuv[0];

      const uvB = faceuv[1];
      const uvC = faceuv[2];
      uvA.set(faceuv[0].x, faceuv[0].y);
      uvB.set(faceuv[1].x, faceuv[1].y);
      uvC.set(faceuv[2].x, faceuv[2].y);

      const centroid = new THREE.Vector3();

      centroid.copy(a).add(b).add(c).divideScalar(3);

      const azi = this.azimuth(centroid);

      this.correctUV(uvA, 0, a, azi, faceuv);
      this.correctUV(uvB, 1, b, azi, faceuv);
      this.correctUV(uvC, 2, c, azi, faceuv);

      // for (let i = 0, j = 0; i < this.vertexBuffer.length; i += 9, j += 6) {
      //   a.set(
      //     this.vertexBuffer[i + 0],
      //     this.vertexBuffer[i + 1],
      //     this.vertexBuffer[i + 2]
      //   );
      //   b.set(
      //     this.vertexBuffer[i + 3],
      //     this.vertexBuffer[i + 4],
      //     this.vertexBuffer[i + 5]
      //   );
      //   c.set(
      //     this.vertexBuffer[i + 6],
      //     this.vertexBuffer[i + 7],
      //     this.vertexBuffer[i + 8]
      //   );

      //   uvA.set(this.uvBuffer[j + 0], this.uvBuffer[j + 1]);
      //   uvB.set(this.uvBuffer[j + 2], this.uvBuffer[j + 3]);
      //   uvC.set(this.uvBuffer[j + 4], this.uvBuffer[j + 5]);

      //   centroid.copy(a).add(b).add(c).divideScalar(3);

      //   const azi = this.azimuth(centroid);

      //   this.correctUV(uvA, j + 0, a, azi);
      //   this.correctUV(uvB, j + 2, b, azi);
      //   this.correctUV(uvC, j + 4, c, azi);
      // }
    },
    correctUV(uv, stride, vector, azi, faceuv) {
      if (uv.x === 1) {
        faceuv[stride].x = uv.x - 1;
      }
      // if (azi > 0 && uv.x === 1) {
      //   faceuv[stride].x = uv.x - 1;
      // }

      if (vector.x === 0 && vector.z === 0) {
        faceuv[stride].x = azi / 2 / Math.PI + 0.5;
      }
    },
    mergeVertices(geometry) {
      var precisionPoints = 4;
      const verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
      const unique = [],
        changes = [];

      const precision = Math.pow(10, precisionPoints);

      for (let i = 0, il = geometry.vertices.length; i < il; i++) {
        const v = geometry.vertices[i];
        const key =
          Math.round(v.x * precision) +
          "_" +
          Math.round(v.y * precision) +
          "_" +
          Math.round(v.z * precision);

        if (verticesMap[key] === undefined) {
          verticesMap[key] = i;
          unique.push(geometry.vertices[i]);
          changes[i] = unique.length - 1;
        } else {
          //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
          changes[i] = changes[verticesMap[key]];
        }
      }

      // if faces are completely degenerate after merging vertices, we
      // have to remove them from the geometry.
      const faceIndicesToRemove = [];

      for (let i = 0, il = geometry.faces.length; i < il; i++) {
        const face = geometry.faces[i];

        face.a = changes[face.a];
        face.b = changes[face.b];
        face.c = changes[face.c];

        const indices = [face.a, face.b, face.c];

        // if any duplicate vertices are found in a Face3
        // we have to remove the face as nothing can be saved
        for (let n = 0; n < 3; n++) {
          if (indices[n] === indices[(n + 1) % 3]) {
            faceIndicesToRemove.push(i);
            break;
          }
        }
      }

      for (let i = faceIndicesToRemove.length - 1; i >= 0; i--) {
        const idx = faceIndicesToRemove[i];

        geometry.faces.splice(idx, 1);

        for (let j = 0, jl = geometry.faceVertexUvs.length; j < jl; j++) {
          geometry.faceVertexUvs[j].splice(idx, 1);
        }
      }

      // Use unique set of vertices

      const diff = geometry.vertices.length - unique.length;
      geometry.vertices = unique;
      return diff;
    },

    constructor(vertices) {
      // default buffer data

      const vertexBuffer = vertices;
      const uvBuffer = [];
      generateUVs();

      // build non-indexed geometry

      return uvBuffer;

      function generateUVs() {
        const vertex = new THREE.Vector3();

        for (let i = 0; i < vertexBuffer.length; i += 3) {
          vertex.x = vertexBuffer[i + 0];
          vertex.y = vertexBuffer[i + 1];
          vertex.z = vertexBuffer[i + 2];

          const u = azimuth(vertex) / 2 / Math.PI + 0.5;
          const v = inclination(vertex) / Math.PI + 0.5;
          uvBuffer.push(u, 1 - v);
        }

        correctUVs();

        correctSeam();
      }

      function correctSeam() {
        // handle case when face straddles the seam, see #3269

        for (let i = 0; i < uvBuffer.length; i += 6) {
          // uv data of a single face

          const x0 = uvBuffer[i + 0];
          const x1 = uvBuffer[i + 2];
          const x2 = uvBuffer[i + 4];

          const max = Math.max(x0, x1, x2);
          const min = Math.min(x0, x1, x2);

          // 0.9 is somewhat arbitrary

          if (max > 0.9 && min < 0.1) {
            if (x0 < 0.2) uvBuffer[i + 0] += 1;
            if (x1 < 0.2) uvBuffer[i + 2] += 1;
            if (x2 < 0.2) uvBuffer[i + 4] += 1;
          }
        }
      }

      function pushVertex(vertex) {
        vertexBuffer.push(vertex.x, vertex.y, vertex.z);
      }

      function getVertexByIndex(index, vertex) {
        const stride = index * 3;

        vertex.x = vertices[stride + 0];
        vertex.y = vertices[stride + 1];
        vertex.z = vertices[stride + 2];
      }

      function correctUVs() {
        const a = new THREE.Vector3();
        const b = new THREE.Vector3();
        const c = new THREE.Vector3();

        const centroid = new THREE.Vector3();

        const uvA = new THREE.Vector2();
        const uvB = new THREE.Vector2();
        const uvC = new THREE.Vector2();

        for (let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6) {
          a.set(vertexBuffer[i + 0], vertexBuffer[i + 1], vertexBuffer[i + 2]);
          b.set(vertexBuffer[i + 3], vertexBuffer[i + 4], vertexBuffer[i + 5]);
          c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]);

          uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]);
          uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]);
          uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]);

          centroid.copy(a).add(b).add(c).divideScalar(3);

          const azi = azimuth(centroid);

          correctUV(uvA, j + 0, a, azi);
          correctUV(uvB, j + 2, b, azi);
          correctUV(uvC, j + 4, c, azi);
        }
      }

      function correctUV(uv, stride, vector, azimuth) {
        if (azimuth < 0 && uv.x === 1) {
          uvBuffer[stride] = uv.x - 1;
        }

        if (vector.x === 0 && vector.z === 0) {
          uvBuffer[stride] = azimuth / 2 / Math.PI + 0.5;
        }
      }

      // Angle around the Y axis, counter-clockwise when looking from above.

      function azimuth(vector) {
        return Math.atan2(vector.z, -vector.x);
      }

      // Angle above the XZ plane.

      function inclination(vector) {
        return Math.atan2(
          -vector.y,
          Math.sqrt(vector.x * vector.x + vector.z * vector.z)
        );
      }
    },
  },
  mounted() {
    //背景
    this.init();
    this.animate();
    this.addLights();
    // this.initBacground();

    this.starForge();

    // var controls = new OrbitControls(this.camera, this.renderer.domElement);

    // this.renderLine();
  },
};
</script>
<style lang="less">
#container {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 1;
}
.configerDiv {
  position: absolute;
  z-index: 2;
  left: 2%;
  top: 20%;
  border-radius: 16px;
  background: #efeeee;
  background: rgba(239, 238, 238, 0.36);
  text-align: center;
  width: 236px;
}
.title {
  width: 120px;
  text-align: center;
  margin-top: 10px;
  user-select: none;
  font-weight: bold;
  width: fit-content;
  color: white;
  font-style: italic;
}
.el-divider--horizontal {
  margin-top: 10px;
}
.el-form-item__label {
  color: white;
}
.el-input__inner {
  padding-left: 2px;
  padding-right: 2px;
}
</style>